#@layout()

#define css()
<link rel="stylesheet" href="#(CPATH)/static/components/jquery-file-upload/css/jquery.fileupload.css"
      xmlns="http://www.w3.org/1999/html">
<link rel="stylesheet" href="#(CPATH)/static/components/bpmn-js/assets/diagram-js.css">
<link rel="stylesheet" href="#(CPATH)/static/components/bpmn-js/assets/bpmn-font/css/bpmn.css">
<style>
    #editor {
        height: 850px;
        background: url() repeat !important;;
    }

    .bjs-powered-by {
        display: none;
    }

    .form-check-input {
        margin-left: -1rem;
    }

    .multi-users {
        display: flex;
        margin-bottom: 0.5rem;
        flex-wrap: wrap;
    }

    .multi-content {
        position: relative;
        margin-right: 0.5rem;
        margin-bottom: 0.5rem;
    }

    .multi-user, .multi-plus {
        border-radius: 50%;
        border: 1px solid #ced4da;
        width: 2.2rem;
        height: 2.2rem;
        line-height: 2.2rem;
        text-align: center;
        font-size: 0;
        background-color: #e9ecef;
        color: #495057;
        display: block;
    }

    .multi-user:first-letter, .multi-plus:first-letter {
        font-size: 1rem;
        font-weight: 400;
    }

    .multi-plus {
        cursor: pointer;
    }

    .multi-minus {
        display: none;
        position: absolute;
        right: 0;
        top: 2px;
        width: 0.8rem;
        height: 0;
        border: 3px solid #a5abb2;
        border-width: 3px 0 0 0;
        cursor: pointer;
        padding: 5px 0;
    }

    .multi-content:hover > .multi-minus {
        display: block;
    }

</style>
#end

#define script()
<script src="#(CPATH)/static/components/jquery-file-upload/js/vendor/jquery.ui.widget.js"></script>
<script src="#(CPATH)/static/components/jquery-file-upload/js/jquery.iframe-transport.js"></script>
<script src="#(CPATH)/static/components/jquery-file-upload/js/jquery.fileupload.js"></script>

<script src="#(CPATH)/static/components/bpmn-js/custom/bpmnutils.js"></script>
<script src="#(CPATH)/static/components/bpmn-js/bpmn-modeler.production.min.js"></script>
<script src="#(CPATH)/static/components/bpmn-js/custom/myContextPadProvider.js"></script>
<script src="#(CPATH)/static/components/bpmn-js/custom/myPaletteProvider.js"></script>
<script src="#(CPATH)/static/components/bpmn-js/custom/myZhTranslateModule.js"></script>
<script src="#(CPATH)/static/components/bpmn-js/custom/flowable/flowableDescriptor.js"></script>
<script src="#(CPATH)/static/components/bpmn-js/custom/flowable/flowableExtensionModule.js"></script>

<script>
    const elementTypeNames = {
        Process: '当前流程',
        SubProcess: '当前流程',
        Task: '任务',
        SendTask: '发送任务',
        ReceiveTask: '接收任务',
        ManualTask: '手动任务',
        BusinessRuleTask: '业务规则任务',
        ServiceTask: '服务任务',
        UserTask: '用户任务',
        ScriptTask: '脚本任务',
        CallActivity: '引用流程',
        SequenceFlow: '连线',
        StartEvent: '开始事件',
        EndEvent: '结束事件',
    }

    var itemHtml = '<a class="multi-content" title="loginname" data-user-id="userid">\n' +
        '                <span class="multi-user">loginname</span>\n' +
        '                <span class="multi-minus"></span>\n' +
        '           </a>';

    const xml = '#(xmlContent ??)';

    //当前属性面板的对象
    var currentElement;

    var bpmnJS = new BpmnJS({
        container: '#editor',
        additionalModules: [myContextPadProvider, myZhTranslateModule, flowableExtensionModule, MyPaletteModule],
        moddleExtensions: {
            flowable: flowableDescriptor
        },
        keyboard: {
            bindTo: document // 或者window，注意与外部表单的键盘监听事件是否冲突
        }
    });

    //xml 加载完成
    bpmnJS.get('eventBus').on('import.done', function (e) {
        console.log("import.done!!!!!");
        currentElement = bpmnJS.get("canvas").getRootElement();
        updatePropertiesPanel();
    });


    bpmnJS.importXML(xml);


    bpmnJS.get('eventBus').on('element.click', function (e) {
        console.log("click:", e.element);
        currentElement = e.element;
        updatePropertiesPanel()
    });


    function updatePropertiesPanel() {
        $("#propertiesPanel>div").hide();
        $("#propertiesPanel .all").show();

        if (!currentElement) {
            return
        }

        var element = currentElement;
        var elementType = element.type;
        elementType = elementType.indexOf("bpmn:") == 0 ? elementType.substring(5) : elementType;
        var elementTypeName = elementTypeNames[elementType];
        if (elementTypeName) {
            $("#elementTitle").text(elementTypeName);
        }

        var businessObject = element.businessObject;
        $("#eid").val(businessObject.id);
        $("#ename").val(businessObject.name);

        $("#propertiesPanel ." + elementType).show();

        $("#propertiesPanel input,#propertiesPanel select,#propertiesPanel textarea").each(function () {
            var bindProp = $(this).attr("data-bind-prop");
            if (bindProp) {
                //若在 flowableDescriptor.js 已经定义的属性，则会在 businessObject 对象里，否则在 businessObject.$attrs 里
                var value = bindProp.indexOf("flowable:") == 0 ? businessObject[bindProp.substring(9)] : businessObject[bindProp]
                value = value || businessObject.$attrs[bindProp];
                $(this).val(value);

                $('.form-control-clear').each(function () {
                    $(this).toggleClass('d-none', !Boolean($(this).siblings('input[type="text"]').val()));
                });
            }
        });

        $(".actions").each(function () {
            var id = $(this).attr('id');
            var objectValue = businessObject.$attrs["flowable:" + id];
            if (objectValue) {
                $(this).prop("checked", true);
            } else {
                $(this).prop("checked", false);
            }
        })


        var multiInstanceLoopCharacteristics = currentElement.businessObject.loopCharacteristics;
        //多实例，StandardLoopCharacteristics 是循环实例
        if (multiInstanceLoopCharacteristics && multiInstanceLoopCharacteristics.$type != "bpmn:StandardLoopCharacteristics") {

            var loopCardinality = multiInstanceLoopCharacteristics.loopCardinality ? multiInstanceLoopCharacteristics.loopCardinality.body : "";
            var completionCondition = multiInstanceLoopCharacteristics.completionCondition ? multiInstanceLoopCharacteristics.completionCondition.body : "";

            $("#loopCardinality").val(loopCardinality);
            $("#collection").val(multiInstanceLoopCharacteristics.collection);
            $("#elementVariable").val(multiInstanceLoopCharacteristics.elementVariable);
            $("#completionCondition").val(completionCondition);

            if (!multiInstanceLoopCharacteristics.isSequential) {
                $("#sequential").text("（并行）");
            } else {
                $("#sequential").text("（串行）");
            }

            if (currentElement.businessObject.$attrs) {
                $('.multi-users>.multi-content').remove();
                var bindUserList = currentElement.businessObject.$attrs["flowable:bindUserList"];
                if (bindUserList && !Array.isArray(bindUserList)) {
                    bindUserList = bindUserList.split(",");
                }
                if (bindUserList && bindUserList.length > 0) {
                    var that = $('.multi-plus');
                    for (let i = 0; i < bindUserList.length; i++) {
                        var userInfo = bindUserList[i].split('#');
                        that.before(itemHtml.replace(/loginname/g, userInfo[1]).replace("userid", userInfo[0]))
                    }
                }
            }
            $("#propertiesPanel .multiInstance").show();

        } else {
            $("#propertiesPanel .multiInstance").hide();
        }


        // 条件表达式
        var conditionExpression = currentElement.businessObject.conditionExpression;
        if (conditionExpression) {
            $("#conditionExpression").val(conditionExpression.body);
        } else {
            $("#conditionExpression").val('');
        }

    }


    var modeling = bpmnJS.get('modeling');

    $("#propertiesPanel input,#propertiesPanel textarea").each(function () {
        var event = $(this).attr("data-bind-event");
        event = event || "keyup";

        if (!$(this).attr("on" + event)) {
            $(this).on(event, function () {
                if (currentElement) {
                    var prop = $(this).attr("data-bind-prop");
                    if (prop) {
                        var val = $(this).val();

                        if (!val && $(this)[0].hasAttribute("required")) {
                            $(this).val(currentElement.businessObject[prop])
                            return;
                        }

                        var newProp = {};
                        // newProp[prop] = val == ''? undefined : val;
                        newProp[prop] = val;
                        modeling.updateProperties(currentElement, newProp);
                    }
                }
            })
        }
    });

    $("#propertiesPanel select").change(function () {
        var val = $(this).val();
        if (val == '') {
            val = undefined;
        }

        var prop = $(this).attr("data-bind-prop");
        if (prop) {
            var val = $(this).val();

            if (!val && $(this)[0].hasAttribute("required")) {
                $(this).val(currentElement.businessObject[prop])
                return;
            }

            var newProp = {};
            newProp[prop] = val == '' ? undefined : val;
            modeling.updateProperties(currentElement, newProp);
        }
    });


    bpmnJS.get('eventBus').on('element.changed', function (event) {
        var changedElement = event.element;
        if (changedElement.type != "bpmn:SequenceFlow") {
            currentElement = event.element;
            updatePropertiesPanel();
        }
    });


    var selectItems;
    //监听对象被选中
    bpmnJS.get('eventBus').on('selection.changed', function (e) {
        selectItems = e.newSelection;
    });


    async function xmlPreview() {
        var result = await bpmnJS.saveXML({format: true});
        var style = '<style>textarea:focus-visible{outline: none}</style>';
        var content = style + '<textarea style="border:none;width: 100%;height: 99%;padding: 10px;">' + result.xml + '</textarea>'
        var options = {
            type: 1,
            title: 'Xml 内容',
            anim: 2,
            shadeClose: true,
            shade: 0.3,
            area: ['80%', '80%'],
            content: content,
        };
        layer.open(options);
    }

    /**
     * 对齐方式
     * @param type left|right|center|top|bottom|middle
     */
    function align(type) {
        if (selectItems && selectItems.length > 1) {
            bpmnJS.get("alignElements").trigger(selectItems, type);
        } else {
            alert('需要选择 2 个以上的对象，才能进行对齐操作。')
        }
    }


    var currentZoomValue = 1;

    /**
     * 放大
     */
    function zoomIn() {
        currentZoomValue += 0.05;
        bpmnJS.get("canvas").zoom(currentZoomValue, "auto")
    }

    /**
     * 缩小
     */
    function zoomOut() {
        currentZoomValue -= 0.05;
        bpmnJS.get("canvas").zoom(currentZoomValue, "auto")
    }


    /**
     * 撤销
     */
    function undo() {
        bpmnJS.get("commandStack").undo()
    }

    /**
     * 重做
     */
    function redo() {
        bpmnJS.get("commandStack").redo()
    }

    /**
     * 显示快捷键
     */
    function showShortcutKeys() {
        var html = '<div class="content bindings-mac" style="padding: 20px">\n' +
            '        <table style="width: 100%">\n' +
            '            <tbody>\n' +
            '            <tr>\n' +
            '                <td>撤消</td>\n' +
            '                <td class="binding">⌘ (Ctrl) + Z</td>\n' +
            '            </tr>\n' +
            '            <tr>\n' +
            '                <td>重做</td>\n' +
            '                <td class="binding">⌘ (Ctrl) + ⇧ (Shift) + Z</td>\n' +
            '            </tr>\n' +
            '            <tr>\n' +
            '                <td>全选</td>\n' +
            '                <td class="binding">⌘ (Ctrl) + A</td>\n' +
            '            </tr>\n' +
            '            <tr>\n' +
            '                <td>删除</td>\n' +
            '                <td class="binding">Delete (删除键)</td>\n' +
            '            </tr>\n' +
            '            <tr>\n' +
            '                <td>编辑文字</td>\n' +
            '                <td class="binding">E</td>\n' +
            '            </tr>\n' +
            '            <tr>\n' +
            '                <td>抓手工具</td>\n' +
            '                <td class="binding">H</td>\n' +
            '            </tr>\n' +
            '            <tr>\n' +
            '                <td>套索工具</td>\n' +
            '                <td class="binding">L</td>\n' +
            '            </tr>\n' +
            '            <tr>\n' +
            '                <td>空间工具</td>\n' +
            '                <td class="binding">S</td>\n' +
            '            </tr>\n' +
            '            </tbody>\n' +
            '        </table>\n' +
            '    </div>'
        var options = {
            type: 1,
            title: '快捷键',
            anim: 2,
            shadeClose: true,
            shade: 0.3,
            area: ['40%', '40%'],
            content: html,
        };
        layer.open(options);
    }

    async function doSaveXml() {
        var flowId = '#(flowTemplate.id ??)';
        var xmlResult = await bpmnJS.saveXML({format: true});
        var svgResult = await bpmnJS.saveSVG();
        var processKey = bpmnJS.get("canvas").getRootElement().id;
        var deploymentCategory = "article"; //部署类别固定为 article

        var content = {
            xmlContent: xmlResult.xml,
            svgContent: svgResult.svg,
            processKey: processKey,
            deploymentCategory: deploymentCategory
        };

        ajaxPost("#(CPATH)/admin/flow/template/doSaveBpmnXmlContent/" + flowId, content, function () {
            showMessage("流程图保存成功。")
        })
    }

    setSaveHotKeyFunction(doSaveXml);

    /**
     * 设置循环基数
     */
    $("#loopCardinality").on("blur", function () {
        setLoopCardinality($(this).val());
    })


    function setLoopCardinality(body) {

        const loopCardinality = bpmnJS.get("bpmnFactory").create("bpmn:Expression");
        loopCardinality.body = body + "";

        var multiInstanceLoopCharacteristics = currentElement.businessObject.loopCharacteristics;
        multiInstanceLoopCharacteristics['loopCardinality'] = loopCardinality;
        loopCardinality.$parent = multiInstanceLoopCharacteristics;

        modeling.updateProperties(currentElement, {
            loopCharacteristics: multiInstanceLoopCharacteristics
        });
    }


    /**
     * 设置数据集
     */
    $("#collection").on("blur", function () {
        var multiInstanceLoopCharacteristics = currentElement.businessObject.loopCharacteristics;
        multiInstanceLoopCharacteristics['collection'] = $(this).val();
        modeling.updateProperties(currentElement, {
            loopCharacteristics: multiInstanceLoopCharacteristics
        });
    })


    /**
     * 设置元素变量
     */
    $("#elementVariable").on("blur", function () {
        var multiInstanceLoopCharacteristics = currentElement.businessObject.loopCharacteristics;
        multiInstanceLoopCharacteristics['elementVariable'] = $(this).val();
        modeling.updateProperties(currentElement, {
            loopCharacteristics: multiInstanceLoopCharacteristics
        });
    })


    /**
     * 设置完成条件
     */
    $("#completionCondition").on("blur", function () {
        var multiInstanceLoopCharacteristics = currentElement.businessObject.loopCharacteristics;

        const completionCondition = bpmnJS.get("bpmnFactory").create("bpmn:Expression");
        completionCondition.body = $(this).val();
        multiInstanceLoopCharacteristics['completionCondition'] = completionCondition;
        completionCondition.$parent = multiInstanceLoopCharacteristics;

        modeling.updateProperties(currentElement, {
            loopCharacteristics: multiInstanceLoopCharacteristics
        });
    })


    /**
     * 条件表达式
     */
    $("#conditionExpression").on("keyup propertychange", function () {
        var expression = $(this).val();
        if (expression && expression != '') {
            const conditionExpression = bpmnJS.get("bpmnFactory").create("bpmn:FormalExpression");
            conditionExpression.body = $(this).val();
            modeling.updateProperties(currentElement, {
                conditionExpression: conditionExpression
            });
        } else {
            modeling.updateProperties(currentElement, {
                conditionExpression: undefined
            });
        }
    })


    /**
     * [允许、拒绝、驳回] 等操作功能
     */
    $(".actions").on("change", function () {
        var checked = $(this).prop("checked");
        var id = $(this).attr("id");

        var property = {};
        property["flowable:" + id] = checked ? true : undefined;

        modeling.updateProperties(currentElement, property);
    })


    function setAuthorToAssignee() {
        $('#assigneeName').val('文章作者').trigger('propertychange');
        $('#assignee').val('${authorId}').trigger('propertychange');
    }


    function setConditionExpression(value) {
        $('#conditionExpression').val('${action == "' + value + '"}').trigger('propertychange');
    }

    function clearConditionExpression() {
        $('#conditionExpression').val('').trigger('propertychange');
    }

    $('.multi-plus').on('click', function () {
        var that = $(this);
        layer.data = {};
        var options = {
            type: 2,
            title: '选择执行用户',
            anim: 2,
            shadeClose: true,
            shade: 0.3,
            area: ['80%', '80%'],
            content: '#(CPATH)/commons/select/user',
            end: function () {

                if (layer.data.loginname && layer.data.id) {

                    var userIds = [];
                    $('.multi-users>a.multi-content').each(function () {
                        userIds.push($(this).attr('data-user-id'));
                    });

                    if (userIds.indexOf(layer.data.id) >= 0) {
                        alert("用户 " + layer.data.loginname + " 已被设置.");
                        return;
                    }

                    if (currentElement) {


                        var userInfos = currentElement.businessObject.$attrs["flowable:bindUserList"];
                        if (!userInfos) {
                            userInfos = [];
                        } else if (!Array.isArray(userInfos)) {
                            userInfos = userInfos.split(",");
                        }

                        userInfos.push(layer.data.id + "#" + layer.data.loginname);
                        setLoopCardinality(userInfos.length);

                        var newProp = {
                            "flowable:bindUserList": userInfos
                        };
                        modeling.updateProperties(currentElement, newProp);
                    }
                }

                // layer.data
            }
        };
        layer.open(options);
    });


    $('.multiInstance').on('click', '.multi-minus', function () {
        var a = $(this).closest("a");
        if (confirm("确定要移除用户 " + a.attr('title') + " 吗？")) {
            a.remove();
        }
        var id = a.attr('data-user-id');
        var userInfos = currentElement.businessObject.$attrs["flowable:bindUserList"];
        if (userInfos && !Array.isArray(userInfos)) {
            userInfos = userInfos.split(",");
        }
        if (userInfos) {
            userInfos = userInfos.filter((item) => {
                return item.indexOf(id + "#") == -1;
            })

            setLoopCardinality(userInfos.length);

            var newProp = {
                "flowable:bindUserList": userInfos
            };
            modeling.updateProperties(currentElement, newProp);
        }
    })


    $(".djs-palette-entries .entry").each(function () {
        //title="Popover title"
        //data-container="body" data-toggle="popover" data-placement="left"
        //data-content="左侧的 Popover 中的一些内容"
        var title = $(this).attr("title");
        $(this).attr("title", "");
        $(this).attr("data-container", "body");
        $(this).attr("data-toggle", "popover");
        $(this).attr("data-trigger", "hover");
        $(this).attr("data-placement", "right");
        $(this).attr("data-content", title);
    })

    $("[data-toggle='popover']").popover();


</script>
#end

#define content()
<section class="content-header">

    <div class="container-fluid">
        <div class="row">
            <div class="col-sm-6">

                <div class="row mb-2">
                    <div class="col-sm-12">
                        <h1>
                            文章审核流程设计
                            <small data-toggle="tooltip" title="" data-placement="right"
                                   data-trigger="hover"><i class="nav-icon far fa-question-circle"></i></small>
                            <small> 首页 / 审核 / 审核流程 / 文章审核流程设计</small>
                        </h1>
                    </div>
                </div>
            </div>
        </div>

    </div><!-- /.container-fluid -->
</section>

<section class="content">

    <div class="row">
        <div class="col-lg-9">
            <div class="card card-outline card-primary">
                <div class="card-header p1">
                    <div class="btn-group">
                        <button type="button" class="btn btn-primary " #disabledIf(flowTemplate && flowTemplate.deployed
                                ??) onclick="doSaveXml()">保存（ctrl+s）
                        </button>
                    </div>

                    <div class="btn-group">
                        <button type="button" class="btn btn-default" onclick="xmlPreview()">XML预览</button>
                    </div>

                    <div class="btn-group">
                        <button type="button" class="btn btn-default" onclick="align('left')"
                                data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover"
                                data-content="向左对齐">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                                 class="bi bi-align-start" viewBox="0 0 16 16">
                                <path fill-rule="evenodd"
                                      d="M1.5 1a.5.5 0 0 1 .5.5v13a.5.5 0 0 1-1 0v-13a.5.5 0 0 1 .5-.5z"/>
                                <path d="M3 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7z"/>
                            </svg>
                        </button>
                        <button type="button" class="btn btn-default" onclick="align('center')" data-container="body"
                                data-toggle="popover" data-placement="bottom" data-trigger="hover"
                                data-content="左右居中对齐">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                                 class="bi bi-align-center" viewBox="0 0 16 16">
                                <path d="M8 1a.5.5 0 0 1 .5.5V6h-1V1.5A.5.5 0 0 1 8 1zm0 14a.5.5 0 0 1-.5-.5V10h1v4.5a.5.5 0 0 1-.5.5zM2 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7z"/>
                            </svg>
                        </button>
                        <button type="button" class="btn btn-default" onclick="align('right')" data-container="body"
                                data-toggle="popover" data-placement="bottom" data-trigger="hover"
                                data-content="向右对齐">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                                 class="bi bi-align-end" viewBox="0 0 16 16">
                                <path fill-rule="evenodd"
                                      d="M14.5 1a.5.5 0 0 0-.5.5v13a.5.5 0 0 0 1 0v-13a.5.5 0 0 0-.5-.5z"/>
                                <path d="M13 7a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V7z"/>
                            </svg>
                        </button>
                    </div>

                    <div class="btn-group">

                        <button type="button" class="btn btn-default" onclick="align('top')" data-container="body"
                                data-toggle="popover" data-placement="bottom" data-trigger="hover"
                                data-content="向上对齐">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                                 class="bi bi-align-top" viewBox="0 0 16 16">
                                <rect width="4" height="12" rx="1" transform="matrix(1 0 0 -1 6 15)"/>
                                <path d="M1.5 2a.5.5 0 0 1 0-1v1zm13-1a.5.5 0 0 1 0 1V1zm-13 0h13v1h-13V1z"/>
                            </svg>
                        </button>
                        <button type="button" class="btn btn-default" onclick="align('middle')" data-container="body"
                                data-toggle="popover" data-placement="bottom" data-trigger="hover"
                                data-content="上下居中对齐">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                                 class="bi bi-align-middle" viewBox="0 0 16 16">
                                <path d="M6 13a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1v10zM1 8a.5.5 0 0 0 .5.5H6v-1H1.5A.5.5 0 0 0 1 8zm14 0a.5.5 0 0 1-.5.5H10v-1h4.5a.5.5 0 0 1 .5.5z"/>
                            </svg>
                        </button>
                        <button type="button" class="btn btn-default" onclick="align('bottom')" data-container="body"
                                data-toggle="popover" data-placement="bottom" data-trigger="hover"
                                data-content="向下对齐">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                                 class="bi bi-align-bottom" viewBox="0 0 16 16">
                                <rect width="4" height="12" x="6" y="1" rx="1"></rect>
                                <path d="M1.5 14a.5.5 0 0 0 0 1v-1zm13 1a.5.5 0 0 0 0-1v1zm-13 0h13v-1h-13v1z"></path>
                            </svg>
                        </button>
                    </div>


                    <div class="btn-group">
                        <button type="button" class="btn btn-default" onclick="zoomOut()" data-container="body"
                                data-toggle="popover" data-placement="bottom" data-trigger="hover"
                                data-content="缩小">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                                 class="bi bi-zoom-out" viewBox="0 0 16 16">
                                <path fill-rule="evenodd"
                                      d="M6.5 12a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zM13 6.5a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0z"/>
                                <path d="M10.344 11.742c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1 6.538 6.538 0 0 1-1.398 1.4z"/>
                                <path fill-rule="evenodd"
                                      d="M3 6.5a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5z"/>
                            </svg>
                        </button>
                        <button type="button" class="btn btn-default" onclick="zoomIn()" data-container="body"
                                data-toggle="popover" data-placement="bottom" data-trigger="hover"
                                data-content="放大">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                                 class="bi bi-zoom-in" viewBox="0 0 16 16">
                                <path fill-rule="evenodd"
                                      d="M6.5 12a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zM13 6.5a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0z"/>
                                <path d="M10.344 11.742c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1 6.538 6.538 0 0 1-1.398 1.4z"/>
                                <path fill-rule="evenodd"
                                      d="M6.5 3a.5.5 0 0 1 .5.5V6h2.5a.5.5 0 0 1 0 1H7v2.5a.5.5 0 0 1-1 0V7H3.5a.5.5 0 0 1 0-1H6V3.5a.5.5 0 0 1 .5-.5z"/>
                            </svg>
                        </button>
                    </div>

                    <div class="btn-group">
                        <button type="button" class="btn btn-default" onclick="redo()" data-container="body"
                                data-toggle="popover" data-placement="bottom" data-trigger="hover"
                                data-content="重做">
                            <i class="fas fa-redo"></i>
                        </button>
                        <button type="button" class="btn btn-default" onclick="undo()" data-container="body"
                                data-toggle="popover" data-placement="bottom" data-trigger="hover"
                                data-content="撤销">
                            <i class="fas fa-undo"></i>
                        </button>
                    </div>
                    <div class="btn-group">
                        <button type="button" class="btn btn-default" onclick="showShortcutKeys()" data-container="body"
                                data-toggle="popover" data-placement="bottom" data-trigger="hover"
                                data-content="显示快捷键">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                                 class="bi bi-keyboard" viewBox="0 0 16 16">
                                <path d="M14 5a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h12zM2 4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H2z"/>
                                <path d="M13 10.25a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25v-.5zm0-2a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25v-.5zm-5 0A.25.25 0 0 1 8.25 8h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 8 8.75v-.5zm2 0a.25.25 0 0 1 .25-.25h1.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-1.5a.25.25 0 0 1-.25-.25v-.5zm1 2a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25v-.5zm-5-2A.25.25 0 0 1 6.25 8h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 6 8.75v-.5zm-2 0A.25.25 0 0 1 4.25 8h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 4 8.75v-.5zm-2 0A.25.25 0 0 1 2.25 8h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 2 8.75v-.5zm11-2a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25v-.5zm-2 0a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25v-.5zm-2 0A.25.25 0 0 1 9.25 6h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 9 6.75v-.5zm-2 0A.25.25 0 0 1 7.25 6h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 7 6.75v-.5zm-2 0A.25.25 0 0 1 5.25 6h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 5 6.75v-.5zm-3 0A.25.25 0 0 1 2.25 6h1.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-1.5A.25.25 0 0 1 2 6.75v-.5zm0 4a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25v-.5zm2 0a.25.25 0 0 1 .25-.25h5.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-5.5a.25.25 0 0 1-.25-.25v-.5z"/>
                            </svg>
                        </button>
                    </div>

                </div>

                <div class="card-body p-0">
                    <div id="editor">
                    </div>
                </div>

            </div>
        </div>
        <div class="col-lg-3">
            <div class="card card-outline card-primary">
                <div class="card-header ">
                    <h3 class="card-title" style="padding: 8px 0">当前对象：<span id="elementTitle"></span></h3>
                </div>
                <!--                 /.card-header-->
                <div class="card-body" id="propertiesPanel">


                    <div class="form-group all">
                        <label for="eid">ID</label>
                        <input type="text" class="form-control" required id="eid" placeholder="对象ID"
                               data-bind-prop="id">
                    </div>

                    <div class="form-group all">
                        <label for="ename">名称</label>
                        <input type="text" class="form-control" id="ename"
                               placeholder="对象名称" data-bind-prop="name">
                    </div>


                    <div class="form-group UserTask">
                        <label for="candidateGroups">操作功能</label>
                        <div class="form-group" style="display: flex">
                            <div class="form-check">
                                <input class="form-check-input actions" id="agreeAction" type="checkbox">
                                <label class="form-check-label" for="agreeAction">同意</label>
                            </div>
                            <div class="form-check">
                                <input class="form-check-input actions" id="refuseAction" type="checkbox">
                                <label class="form-check-label" for="refuseAction">拒绝</label>
                            </div>
                            <div class="form-check">
                                <input class="form-check-input actions" id="rebutAction" type="checkbox">
                                <label class="form-check-label" for="rebutAction">驳回</label>
                            </div>
                            <div class="form-check">
                                <input class="form-check-input actions" id="stopAction" type="checkbox">
                                <label class="form-check-label" for="stopAction">停止</label>
                            </div>
                        </div>
                    </div>


                    <div class="form-group UserTask">
                        <label for="assignee">分配人员</label>
                        <div class="input-group">
                            <input type="hidden" class="clear" name="assignee" id="assignee"
                                   data-bind-event="propertychange" data-bind-prop="flowable:assignee">
                            <input type="text" class="form-control" placeholder="哪些人员来处理？" readonly id="assigneeName"
                                   name="assigneeName" data-bind-event="propertychange"
                                   data-bind-prop="flowable:assigneeName">
                            <div class="form-control-clear d-none"><i class="fas fa-times"></i></div>
                            <div class="input-group-append">
                                <button class="btn input-group-text" type="button" open-type="layer"
                                        data-layer-content="#(CPATH)/commons/select/user"
                                        data-layer-binds="#assigneeName:loginname,#assignee:id"><i
                                        class="fas fa-user-plus"></i></button>
                            </div>
                        </div>

                        <div style="margin-top: 5px">
                            <button type="button" class="btn btn-default btn-sm" onclick="setAuthorToAssignee()">
                                <i class="fas fa-user"></i> 文章作者
                            </button>
                        </div>
                    </div>


                    <div class="form-group UserTask">
                        <label for="candidateGroups">分配部门</label>
                        <select class="form-control" id="candidateGroups" data-bind-prop="flowable:candidateGroups">
                            <option value="">==无任何部门==</option>
                            #for(c : departments)
                            <option value="#(c.id)">#(c.layerString) #(c.name)</option>
                            #end
                        </select>
                    </div>


                    <div class="form-group ServiceTask">
                        <label for="serviceClass">服务对象 * </label>
                        <select type="text" class="form-control" id="serviceClass" data-bind-prop="flowable:class">
                            <option value="">请选择服务对象</option>
                            #for(serviceTaskDelegate : serviceTaskDelegates)
                            <option value="#(serviceTaskDelegate.className ??)">#(serviceTaskDelegate.title ??)</option>
                            #end
                        </select>
                    </div>


                    <div class="form-group row multiInstance">
                        <div class="12">
                            <h5>多实例 <span id="sequential"></span></h5>
                        </div>
                    </div>


                    <div class="multi-users multiInstance">


                        <a class="multi-plus">
                            +
                        </a>
                    </div>


                    <!--                    <div class="form-group multiInstance">-->
                    <!--                        <label for="loopCardinality">循环基数(Loop Cardinality)</label>-->
                    <!--                        <input type="text" class="form-control" id="loopCardinality" placeholder="设置循环多少次"/>-->
                    <!--                    </div>-->


                    <!--                    <div class="form-group multiInstance">-->
                    <!--                        <label for="collection">数据集(Collection)</label>-->
                    <!--                        <input type="text" class="form-control" id="collection"-->
                    <!--                               placeholder="多实例的数据集"/>-->
                    <!--                    </div>-->


                    <!--                    <div class="form-group multiInstance">-->
                    <!--                        <label for="elementVariable">元素变量(Element Variable)</label>-->
                    <!--                        <input type="text" class="form-control" id="elementVariable"-->
                    <!--                               placeholder="每个实例的变量"/>-->
                    <!--                    </div>-->


                    <div class="form-group multiInstance">
                        <label for="completionCondition">完成条件(Completion Condition)</label>
                        <textarea rows="2" class="form-control" id="completionCondition"
                                  placeholder="多个实例完成的条件" style="font-size: 14px"
                                  spellcheck="false"></textarea>
                        <p class="text-muted">
                            表达式参考，请点击 <a href="#(CPATH)/admin/article/bpmn/description" open-type="layer">这里</a>
                        </p>
                    </div>


                    <div class="form-group multiInstance">
                        <label for="agreeCondition">同意条件（同意发布文章的条件）</label>
                        <textarea rows="2" class="form-control" id="agreeCondition"
                                  placeholder="设置同意发布文章的条件" data-bind-prop="flowable:agreeCondition" style="font-size: 14px"
                                  spellcheck="false"></textarea>
                        <p class="text-muted">
                            表达式参考，请点击 <a href="#(CPATH)/admin/article/bpmn/description" open-type="layer">这里</a>
                        </p>
                    </div>


                    <div class="form-group SequenceFlow">
                        <label for="conditionExpression">条件表达式(Expression)</label>
                        <input type="text" class="form-control" id="conditionExpression"
                               placeholder="流向条件是..."/>

                        <div style="margin-top: 5px">
                            <button type="button" class="btn btn-default btn-sm"
                                    onclick="setConditionExpression('agree')">
                                同意
                            </button>
                            <button type="button" class="btn btn-default btn-sm"
                                    onclick="setConditionExpression('refuse')">
                                拒绝
                            </button>
                            <button type="button" class="btn btn-default btn-sm"
                                    onclick="setConditionExpression('rebut')">
                                驳回
                            </button>
                            <button type="button" class="btn btn-default btn-sm" onclick="clearConditionExpression()">
                                清空
                            </button>
                        </div>

                    </div>

                </div>
            </div>
        </div>
    </div>

</section>

#end
